package alex.thread.cyclic;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CyclicBarrierTest2 {

    public static void main(String[] args) {
        for (int item = 1; item <= 10; item++) {
            int sleep = 0;
            if (item == 10) {
                sleep = 10;
            }

            Thread player = new Thread(new Player2("玩家" + item, sleep));
            player.start();


            if (item == 5) {
                try {
                    TimeUnit.SECONDS.sleep(item);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println("玩家" + item + "有事, 需要先开始啦...");
                player.interrupt();
            }
        }
    }
}

class Player2 implements Runnable {

    private static final CyclicBarrier barrier = new CyclicBarrier(10);

    private String name;
    private int sleep;

    public Player2(String name, int sleep) {
        this.name = name;
        this.sleep = sleep;
    }

    @Override
    public void run() {
        eat();
        drive();
    }

    void eat() {
        long startTime = 0;
        try {
            TimeUnit.SECONDS.sleep(sleep);
            startTime = System.currentTimeMillis();
            // 等着一起eat.
            System.out.println(this.name + "到啦!");
            if ("玩家1".equals(this.name)) {
                barrier.await(3, TimeUnit.SECONDS);
            } else {
                barrier.await();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }

        long endTime = System.currentTimeMillis();
        System.out.println(this.name + " wait " + (endTime - startTime) + " ms, 可以开始吃饭了!");
    }

    void drive() {
        try {
            TimeUnit.SECONDS.sleep(this.sleep);
            long startTime = System.currentTimeMillis();

            // 等着一起drive.
            barrier.await();
            long endTime = System.currentTimeMillis();
            System.out.println(this.name + " wait " + (endTime - startTime) + " ms, 可以发车了!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}
